package com.ecarx.library_base.scoket;

import android.util.Log;

import com.ecarx.library_base.base_util.GsonUtils;
import com.ecarx.library_base.base_util.ThreadUtils;
import com.ecarx.library_base.scoket.model.SocketResponse;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class SocketClient {

    private static final String TAG = "SocketClient";

    private boolean isConnected;


    private final String mHost;

    private final int mPort;

    private final SocketCallback mSocketCallback;

    private Socket mSocket;

    private BufferedReader mBufferedReader;

    private PrintWriter mPrintWriter;

    public SocketClient(String host, int port, SocketCallback socketCallback) {
        this.mHost = host;
        this.mPort = port;
        this.mSocketCallback = socketCallback;
    }

    public void start() {
        if (isConnected && mSocket != null) {
            Log.d(TAG, "start: task is running");
            return;
        }
        isConnected = true;
        ThreadUtils.getCachedPool().execute(new Runnable() {
            @Override
            public void run() {

                //创建Socket链接
                try {
                    Log.d(TAG, "start: " + mHost + ":" + mPort);
                    mSocket = new Socket(mHost, mPort);
                    mPrintWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                            mSocket.getOutputStream(), StandardCharsets.UTF_8)), true);
                    mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream(), StandardCharsets.UTF_8));
		    if (mSocketCallback != null) {
                        mSocketCallback.onConnected();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    callbackError();
                    return;
                }
                //异常重试次数
                int tryCont = 10;
                // 循环接收服务端的消息
                while (isConnected) {
                    String msg;
                    try {
                        msg = mBufferedReader.readLine();
                        tryCont = 0;
                    } catch (Exception e) {
                        e.printStackTrace();
                        tryCont--;
                        if (tryCont <= 0) {
                            break;
                        }
                        continue;
                    }
                    if (msg != null && !msg.isEmpty()) {
                        SocketResponse socketMsg;
                        try {
                            socketMsg = GsonUtils.fromJson(msg, SocketResponse.class);
                        } catch (Exception e) {
                            e.printStackTrace();
                            break;
                        }
                        mSocketCallback.onSocketCallback(socketMsg);
                    } else if (!isServerActive(mSocket)) {
                        //服务端断开
                        Log.d(TAG, "start: server is notActive");
                        break;
                    }
                }
                callbackError();
            }
        });
    }

    private void callbackError() {
        Log.d(TAG, "callbackError: ");
        release();
        if (isConnected) {
            mSocketCallback.onError();
            isConnected = false;
        }
    }

    public void sendMsg(String msg) {
        ThreadUtils.getCachedPool().execute(new Runnable() {
            @Override
            public void run() {
                if (mPrintWriter != null) {
                    mPrintWriter.println(msg);
                }
            }
        });
    }

    public void stop() {
        isConnected = false;
        release();
    }

    private void release() {
        try {
            if (mSocket != null) {
                mSocket.close();
                mSocket = null;
            }
            if (mPrintWriter != null) {
                mPrintWriter.close();
                mPrintWriter = null;
            }
            if (mBufferedReader != null) {
                mBufferedReader.close();
                mBufferedReader = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private boolean isServerActive(Socket socket) {
        if (socket == null) {
            return false;
        }
        try {
            socket.sendUrgentData(0);//发送1个字节的紧急数据，默认情况下，服务器端没有开启紧急数据处理，不影响正常通信
            return true;
        } catch (Exception se) {
            se.printStackTrace();
            return false;
        }
    }

    public interface SocketCallback {

        void onConnected();

        void onSocketCallback(SocketResponse line);

        void onError();
    }
}
